/* eslint-disable react/no-unused-state */
import React from 'react';
import { Button, Balloon } from '@teamix/ui';
import { Content, Header, Section, ButtonIcon, Title, YunxiaoIcon } from '@alife/devops-ui';
import utils from 'utils';
import docs from 'utils/docs';
import Wcontainer from '@alife/aisc-widgets/lib/Wcontainer';
import Wradar from '@alife/aisc-widgets/lib/Wradar';
import ListLoading from 'atComponents/ListLoading';
import { navigate, navigateOpen } from 'utils/router';
import Skeleton from './skeleton';
import ProTag from 'components/proTag';
import track, { enterPage } from 'utils/track';
import BillingHander from 'components/billing';
import moment from 'moment';
import './index.scss';
import intl from '../../../../../../../../../../locale';

const prefix = 'risk-overview';
const levelMap = {
  danger: {
    color: '#e62412',
    title: intl.get({ id: 'code-assets.containers.overview.HighRisk', defaultMessage: '高风险' }),
    desc: intl.get({
      id: 'code-assets.containers.overview.YourAssetSecurityDefenseCapability',
      defaultMessage: '您的资产安全防御的能力较弱，建议尽快加固安全防护体系',
    }),
  },

  warning: {
    color: '#fa8c15',
    title: intl.get({ id: 'code-assets.containers.overview.MediumRisk', defaultMessage: '中风险' }),
    desc: intl.get({
      id: 'code-assets.containers.overview.ThereAreManySecurityRisks',
      defaultMessage: '您的资产存在较多安全风险，建议及时加固安全防护体系',
    }),
  },

  low: {
    color: '#1b9aee',
    title: intl.get({ id: 'code-assets.containers.overview.LowRisk', defaultMessage: '低风险' }),
    desc: intl.get({
      id: 'code-assets.containers.overview.YourAssetsHaveSecurityRisks',
      defaultMessage: '您的资产存在安全风险，建议尽快加固安全防护体系',
    }),
  },

  good: {
    color: '#15ad31',
    title: intl.get({ id: 'code-assets.containers.overview.Good', defaultMessage: '良好' }),
    desc: intl.get({
      id: 'code-assets.containers.overview.ThereAreFewPotentialRisks',
      defaultMessage: '您的资产目前隐患较少，还有提升空间哦～',
    }),
  },

  excellent: {
    color: '#15ad31',
    title: intl.get({ id: 'code-assets.containers.overview.Excellent', defaultMessage: '优秀' }),
    desc: intl.get({
      id: 'code-assets.containers.overview.CongratulationsYourAssetsAreIn',
      defaultMessage: '恭喜您，您的资产安全状态很好，请继续保持！',
    }),
  },
};

export default class RiskOverview extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      billingVisible: false,
    };
  }

  componentDidMount() {
    // this.props.getOverviewScore();
    // this.props.getAllCount();
    document.title = intl.get({
      id: 'code-assets.containers.overview.SecurityOverviewCloudEffectCodeup',
      defaultMessage: '安全总览 · 云效 Codeup',
    });
    enterPage('Organization-Settings-Risk Control');
    const { scoreInfo = {}, isLoadingScore, refreshOverviewScore } = this.props;
    if (!isLoadingScore && scoreInfo) {
      refreshOverviewScore();
    }
  }

  getStateData = () => {
    const { settings = {} } = this.props;
    const { planType } = settings;
    return {
      items: [
        {
          title: intl.get({
            id: 'code-assets.containers.overview.PermissionControl',
            defaultMessage: '权限控制',
          }),

          details: [
            {
              key: 'isWhiteListOpen',
              label: intl.get({
                id: 'code-assets.containers.overview.IpAddressWhitelistDisabled',
                defaultMessage: '未开启 IP 白名单',
              }),

              url: '/settings/security',
              action: 'click_resolve_ip',
            },

            {
              label: intl.get({
                id: 'code-assets.containers.overview.TheEnterpriseAdministratorAndThe',
                defaultMessage: '未区分企业管理员和企业代码管理员（开启了同步云效企业管理员）',
              }),

              key: 'isSynchronization',
              url: '/settings/admins',
              action: 'click_resolve_orgadmin',
            },
          ],
        },

        {
          title: intl.get({
            id: 'code-assets.containers.overview.MemberBehaviorSecurity',
            defaultMessage: '成员行为安全',
          }),

          details: [
            {
              key: 'isVariabilityNotice',
              label: (
                <span>
                  {intl.get({
                    id: 'code-assets.containers.overview.VisibilityChangeNotificationsAreNot',
                    defaultMessage: '可见性变更通知未全部开启',
                  })}

                  <ProTag planType={planType} />
                </span>
              ),

              url: '/settings/security_notify',
              action: 'click_resolve_alarm',
              isPro: true,
            },

            {
              key: 'is_branch_ok',
              label: intl.get({
                id: 'code-assets.containers.overview.SomeDatabasesDoNotHave',
                defaultMessage: '部分库未设置保护分支',
              }),

              action: 'click_resolve_protect',
              url: docs('branchSettings'),
            },

            {
              key: 'is_commit_check_ok',
              label: intl.get({
                id: 'code-assets.containers.overview.ForcePushProhibitionOrCode',
                defaultMessage: '未设置禁止强制推送或代码属主检查',
              }),

              action: 'click_resolve_forcepush',
              url: '/settings/repository_permissions',
            },

            {
              key: 'is_sensitive_behavior_enable',
              label: (
                <span>
                  {intl.get({
                    id: 'code-assets.containers.overview.SensitiveBehaviorMonitoringDisabled',
                    defaultMessage: '未开启敏感行为监测',
                  })}

                  <ProTag planType={planType} />
                </span>
              ),

              url: '/settings/member_behavior_security',
              action: 'click_resolve_behavior',
              isPro: true,
            },

            {
              key: 'is_sensitive_behavior_enable_without_whitelist',
              label: (
                <span>
                  {intl.get({
                    id: 'code-assets.containers.overview.RemoveTheSensitiveBehaviorMonitoring',
                    defaultMessage: '取消敏感行为监测白名单',
                  })}

                  <ProTag planType={planType} />
                </span>
              ),

              url: '/settings/member_behavior_security?nav=whitelist',
              action: 'click_resolve_behaviorwhite',
              isPro: true,
            },

            {
              key: 'is_sensitive_behavior_enable_with_notify',
              label: (
                <span>
                  {intl.get({
                    id: 'code-assets.containers.overview.SensitiveBehaviorAlertNotificationsAre',
                    defaultMessage: '敏感行为告警通知未全部开启',
                  })}

                  <ProTag planType={planType} />
                </span>
              ),

              url: '/settings/security_notify',
              action: 'click_resolve_behavioralarm',
              isPro: true,
            },
          ],
        },

        {
          title: intl.get({
            id: 'code-assets.containers.overview.CodeContentSecurity',
            defaultMessage: '代码内容安全',
          }),

          details: [
            {
              key: 'is_service_rate_ok',
              label: intl.get({
                id: 'code-assets.containers.overview.CodeScanningIsDisabledFor',
                defaultMessage: '代码库未开启代码扫描',
              }),

              action: 'click_resolve_scan',
              url: '/settings/code_content_security',
            },

            {
              key: 'is_issue_rate_ok',
              label: intl.get({
                id: 'code-assets.containers.overview.ThousandLineProblemRate',
                defaultMessage: '千行问题率',
              }),

              action: 'click_resolve_rate',
            },
          ],
        },
      ],
    };
  };

  getAnalysisItems = () => {
    const { countInfo = {}, scoreInfo = {} } = this.props;
    const sensitive_info_detection_count =
      (scoreInfo &&
        scoreInfo.organizationSecurityScoreDo &&
        scoreInfo.organizationSecurityScoreDo.sensitiveIssueProjectCount) ||
      0;
    const dependency_analysis_count =
      (scoreInfo &&
        scoreInfo.organizationSecurityScoreDo &&
        scoreInfo.organizationSecurityScoreDo.dependencyIssueProjectCount) ||
      0;
    return [
      [
        {
          count: countInfo.operation_count || 0,
          desc: intl.get({
            id: 'code-assets.containers.overview.AbnormalBehaviorsOfMembersIn',
            defaultMessage: '近 15 天成员异常行为数',
          }),

          onClick: () => {
            navigate('/settings/member_behavior_security');
            track({
              action: 'click_behavior',
              page: 'Org-Security',
              type: '',
              control: '',
            });
          },
        },

        {
          count: countInfo.trashes_count,
          desc: intl.get({
            id: 'code-assets.containers.overview.TheNumberOfCodeLibraries',
            defaultMessage: '即将自动删除的代码库数',
          }),

          onClick: () => {
            navigate('/trashes');
            track({
              action: 'click_recycle',
              page: 'Org-Security',
              type: '',
              control: '',
            });
          },
        },
      ],

      [
        {
          count: sensitive_info_detection_count,
          desc: intl.get({
            id: 'code-assets.containers.overview.CodeLibrariesWithSensitiveInformation',
            defaultMessage: '存在敏感信息泄漏风险的代码库',
          }),

          onClick: () => {
            navigate('/settings/code_content_security');
            track({
              action: 'click_sensitive',
              page: 'Org-Security',
              type: '',
              control: '',
            });
          },
        },

        {
          count: dependency_analysis_count,
          desc: intl.get({
            id: 'code-assets.containers.overview.CodeLibrariesWithDependencyPackage',
            defaultMessage: '存在依赖包漏洞风险的代码库',
          }),

          tooltip: intl.get({
            id: 'code-assets.containers.overview.EnterprisesAreBuildingVulnerabilityDependent',
            defaultMessage: '企业依赖漏洞安全报表建设中',
          }),
        },
      ],
    ];
  };

  getWradarData = () => {
    const { scoreInfo } = this.props;
    if (!(scoreInfo && scoreInfo.organizationSecurityScoreDo)) {
      return [];
    }
    const { organizationSecurityScoreDo } = scoreInfo;
    const data = [
      {
        name: intl.get({ id: 'code-assets.containers.overview.Score', defaultMessage: '得分' }),
        data: [
          [
            intl.get({
              id: 'code-assets.containers.overview.PermissionControl',
              defaultMessage: '权限控制',
            }),

            organizationSecurityScoreDo.authorityControlCore || 0,
          ],

          [
            intl.get({
              id: 'code-assets.containers.overview.CodeContentSecurity',
              defaultMessage: '代码内容安全',
            }),

            organizationSecurityScoreDo.codeContentScore || 0,
          ],

          [
            intl.get({
              id: 'code-assets.containers.overview.MemberBehaviorSecurity',
              defaultMessage: '成员行为安全',
            }),

            organizationSecurityScoreDo.memberBehaviorScore || 0,
          ],
        ],
      },
    ];

    return data;
  };

  getWradarInfo = () => {
    const { scoreInfo } = this.props;
    if (!(scoreInfo && scoreInfo.organizationSecurityScoreDo)) {
      return {
        data: [],
        config: {},
      };
    }
    const data = this.getWradarData();
    const { levelInfo } = this.getLevelInfo();

    const config = {
      colors: [levelInfo.color || 'gray'],
      area: true,
      legend: false,
      xAxis: {
        customConfig: {
          label: {
            htmlTemplate: (value) => {
              // 获取数据要在函数内，否则数据更新时，label不更新
              const curData = this.getWradarData();
              const dataMap = {};
              for (const i of curData[0].data) {
                const name = i[0];
                const curValue = i[1];
                dataMap[name] = curValue;
              }
              return `<span class="${prefix}-wradar-label">
                  <span class="${prefix}-wradar-label-title">${dataMap[value]}</span>
                  <br />
                  <span class="${prefix}-wradar-label-desc">${value}</span>
                </span>`;
            },
          },
        },
      },

      yAxis: {
        customConfig: {
          label: null,
        },
      },
    };

    return {
      data,
      config,
    };
  };

  getLevelInfo = () => {
    const { scoreInfo } = this.props;
    if (
      !(
        scoreInfo &&
        scoreInfo.organizationSecurityScoreDo &&
        scoreInfo.organizationSecurityScoreDo.securityScore
      )
    ) {
      return {
        level: '',
        levelInfo: {},
        securityScore: '',
      };
    }

    const { securityScore, authorityControlCore, codeContentScore, memberBehaviorScore } =
      scoreInfo.organizationSecurityScoreDo;

    const minScore = Math.min(authorityControlCore, codeContentScore, memberBehaviorScore);
    let level = '';
    if (minScore < 60) {
      level = 'danger';
    } else if (minScore < 80) {
      level = 'warning';
    } else if (minScore < 90) {
      level = 'low';
    } else if (minScore < 100) {
      level = 'good';
    } else {
      level = 'excellent';
    }

    return {
      level,
      levelInfo: levelMap[level],
      securityScore,
    };
  };

  render() {
    const { items } = this.getStateData();
    const { settings = {} } = this.props;
    const { planType } = settings;
    const {
      scoreInfo = {},
      isLoadingOverviewCount,
      isLoadingScore,
      enterprisePackage,
    } = this.props;
    const analysisItems = this.getAnalysisItems();

    if (isLoadingScore) {
      return <ListLoading />;
    }
    if (!scoreInfo) {
      return null;
    }

    if (scoreInfo && !scoreInfo.organizationSecurityScoreDo) {
      return <ListLoading />;
      // organizationSecurityScoreDo在调用计算接口后，一定存在值，所以不存在的时候需要调接口
      // return (
      //   <ListEmpty
      //     type="card"
      //     content="暂无得分"
      //     description="点击按钮计算分数吧"
      //     imgType="org-list-empty"
      //     className="mt20"
      //     btns={[
      //       <Button
      //         type="primary"
      //         onClick={() => {
      //           refreshOverviewScore && refreshOverviewScore();
      //         }}
      //       >
      //         计算得分
      //       </Button>,
      //     ]}
      //   />
      // );
    }
    const { state, integrationServiceRate, issueRate } = scoreInfo.organizationSecurityScoreDo;
    const { data, config } = this.getWradarInfo();
    const { level, levelInfo } = this.getLevelInfo();
    // const billingOrgid = enterprisePackage && enterprisePackage.order_info && enterprisePackage.order_info.order_id;
    // const billingOrgidDate = enterprisePackage && enterprisePackage.order_info && enterprisePackage.order_info.end_date ? moment(enterprisePackage.order_info.end_date).diff(moment(), 'day') : -1;

    const billingType =
      enterprisePackage &&
      enterprisePackage.plan_type === 'premiumVersion' &&
      (enterprisePackage.status === 'limit' || enterprisePackage.status === 'strictLimit');
    const billingTryOrder =
      enterprisePackage &&
      enterprisePackage.plan_type !== 'premiumVersion' &&
      ((enterprisePackage && enterprisePackage.is_can_use_trial_feature) ||
        (enterprisePackage && enterprisePackage.is_has_used_trial_feature));

    const localValue = window.localStorage.getItem(`codeBillinglimit-${window.config.orgId}`);
    const dataValue = moment().format('YYYY/MM/DD');
    const billingVisibless = localValue
      ? JSON.parse(localValue).filter((va) => va === dataValue)
      : [];
    const limitstatus = enterprisePackage.status === 'limit' && billingVisibless.length > 0;

    // const firstlocalValue = window.localStorage.getItem(`codeFirstBilling-${window.config.orgId}`);
    // const firstdataValue = moment().format('YYYY/MM/DD');
    // const firstbillingVisible = firstlocalValue ? JSON.parse(firstlocalValue).filter(va => va === firstdataValue) : [];
    // const firstlimitstatus = billingTryOrder && firstbillingVisible.length > 0;
    return (
      <>
        <Header
          title={intl.get({
            id: 'code-assets.containers.sensitiveInfoReport.CodeContentSecurity',
            defaultMessage: '安全总览',
          })}
        />
        <Content style={{ position: 'relative' }}>
          <Section
            title={'安全评分'}
            operation={
              <div className={`${prefix}-extra`}>
                <Button
                  type="primary"
                  text
                  style={{ marginRight: 12 }}
                  onClick={() => {
                    this.props.refreshOverviewScore();
                    track({
                      action: 'refresh score',
                      page: 'Organization-Settings-Risk Control',
                      type: '',
                      control: '',
                    });
                  }}
                >
                  {intl.get({
                    id: 'code-assets.containers.overview.RefreshScore',
                    defaultMessage: '刷新分数',
                  })}
                </Button>
                {intl.get({
                  id: 'code-assets.containers.overview.DataUpdatedOn',
                  defaultMessage: '数据更新于',
                })}
                &nbsp;
                {utils.getBeautyTime(
                  (scoreInfo.organizationSecurityScoreDo &&
                    scoreInfo.organizationSecurityScoreDo.gmtModified) ||
                    '',
                )}
              </div>
            }
          >
            <div className={`${prefix} ${level}`}>
              {/* 概览和问题详情 */}
              <div className={`${prefix}-detail`}>
                <div className={`${prefix}-detail-left`}>
                  <Wcontainer>
                    <Wradar height="300" config={config} data={data} />
                  </Wcontainer>
                  <div
                    className={`${prefix}-detail-left-overlay ${
                      state === 'running' ? 'loading' : ''
                    }`}
                  >
                    {state === 'running' ? (
                      <div style={{ textAlign: 'center' }}>
                        <YunxiaoIcon type="loading-fill" className="loading-icon" />
                        <p>
                          {intl.get({
                            id: 'code-assets.containers.overview.CalculatingSecurityScore',
                            defaultMessage: '安全评分计算中',
                          })}
                        </p>
                      </div>
                    ) : null}
                  </div>
                </div>
                <div className={`${prefix}-detail-right`}>
                  {state === 'running' ? (
                    <Skeleton />
                  ) : (
                    <div className={`${prefix}-detail-right-content`}>
                      <div className={`${prefix}-level`}>
                        <div className={`${prefix}-level-title`}>
                          <span className={`${prefix}-level-title-strong`}>{levelInfo.title}</span>/
                          {intl.get({
                            id: 'code-assets.containers.overview.SecurityRating',
                            defaultMessage: '/ 安全评级',
                          })}
                          <Balloon
                            closable={false}
                            trigger={
                              <ButtonIcon
                                text
                                style={{ padding: 0, marginLeft: 4, position: 'relative', top: -2 }}
                                name="question-line"
                              />
                            }
                            align="t"
                          >
                            <a
                              target="_blank"
                              rel="noreferrer"
                              onClick={() => {
                                track({
                                  action: 'risk-score-rule',
                                  page: 'Org-Security',
                                  type: '',
                                  control: '',
                                });
                              }}
                              href={docs('risk-score-rule')}
                            >
                              {intl.get({
                                id: 'code-assets.containers.overview.ScoringRules',
                                defaultMessage: '评分规则',
                              })}
                            </a>
                          </Balloon>
                        </div>
                        <div className={`${prefix}-level-desc`}>
                          <Title trigger={<span>{levelInfo.desc}</span>} align="t">
                            {levelInfo.desc}
                          </Title>
                        </div>
                      </div>
                      <div className={`${prefix}-list`}>
                        {items.map((item) => {
                          const { details } = item;
                          const curDetails = details.filter((detail) => {
                            return !scoreInfo[detail.key];
                          });
                          if (!curDetails.length) {
                            return null;
                          }
                          return (
                            <div className={`${prefix}-list-item`}>
                              <div className={`${prefix}-list-item-title`}>
                                {item.title} · {curDetails.length}
                              </div>
                              <div className={`${prefix}-list-item-infos`}>
                                {curDetails.map((d) => {
                                  const labelJsx = (
                                    <span>
                                      {d.key === 'is_service_rate_ok'
                                        ? `${100 - integrationServiceRate}% `
                                        : ''}
                                      {d.label}
                                      {d.key === 'is_issue_rate_ok' ? ` ${issueRate}%` : ''}
                                    </span>
                                  );

                                  return (
                                    <div className={`${prefix}-info`}>
                                      <div className={`${prefix}-info-label`}>
                                        <Title trigger={labelJsx} align="t">
                                          {labelJsx}
                                        </Title>
                                      </div>
                                      <div className={`${prefix}-info-btn`}>
                                        {d.url ? (
                                          <Button
                                            type="primary"
                                            text
                                            onClick={() => {
                                              // if (d.isPro && (billingOrgidDate < 0 || !billingOrgid)) {
                                              if (d.isPro && billingType && limitstatus) {
                                                navigateOpen(d.url, '_blank');
                                                track({
                                                  action: d.action,
                                                  page: 'Org-Security',
                                                  type: '',
                                                  control: '',
                                                });
                                              } else if (
                                                d.isPro &&
                                                (billingType || billingTryOrder)
                                              ) {
                                                this.setState({
                                                  billingVisible: true,
                                                });
                                              } else {
                                                navigateOpen(d.url, '_blank');
                                                track({
                                                  action: d.action,
                                                  page: 'Org-Security',
                                                  type: '',
                                                  control: '',
                                                });
                                              }
                                            }}
                                          >
                                            {intl.get({
                                              id: 'code-assets.containers.overview.Set',
                                              defaultMessage: '设置',
                                            })}
                                          </Button>
                                        ) : null}
                                      </div>
                                    </div>
                                  );
                                })}
                              </div>
                            </div>
                          );
                        })}
                      </div>
                    </div>
                  )}
                </div>
              </div>
            </div>
          </Section>
          {!isLoadingOverviewCount && (
            <Section
              title={
                <>
                  {intl.get({
                    id: 'code-assets.containers.overview.SecurityAnalysis',
                    defaultMessage: '安全分析',
                  })}
                  <ProTag planType={planType} />
                </>
              }
            >
              <div className={`${prefix}-analysis-list`}>
                {
                  // eslint-disable-next-line no-nested-ternary
                  billingType && limitstatus
                    ? null
                    : (billingType || billingTryOrder) && (
                    <div className={`${prefix}-analysis-list-billing`}>
                      <div className={`${prefix}-analysis-list-billing-title`}>
                        {intl.get({
                              id: 'code-assets.containers.overview.StatisticalAnalysisOfEnterpriseRisk',
                              defaultMessage: '统计分析企业风险现状',
                            })}
                      </div>
                      <div
                        className={`${prefix}-analysis-list-billing-desc`}
                        onClick={() => {
                              this.setState({ billingVisible: true });
                            }}
                      >
                        {intl.get({
                              id: 'code-assets.containers.overview.EnableNow',
                              defaultMessage: '立即启用',
                            })}
                      </div>
                    </div>
                      )
                }

                {analysisItems.map((analysisItem) => {
                  return (
                    <div className={`${prefix}-analysis-item-container`}>
                      {analysisItem.map((item) => {
                        const trigger = (
                          <div
                            className={`${prefix}-analysis-item`}
                            onClick={() => {
                              item.onClick && item.onClick();
                            }}
                          >
                            <div className={`${prefix}-analysis-item-img`}>
                              <img
                                src="https://img.alicdn.com/imgextra/i1/O1CN01P3azvW1SmPF8d63mT_!!6000000002289-2-tps-120-120.png"
                                alt=""
                              />
                            </div>
                            <div className={`${prefix}-analysis-item-info`}>
                              <div className={`${prefix}-analysis-item-info-count`}>
                                {item.count}
                              </div>
                              <div className={`${prefix}-analysis-item-info-desc`}>{item.desc}</div>
                            </div>
                          </div>
                        );

                        return item.tooltip ? (
                          <Balloon.Tooltip align="t" trigger={trigger}>
                            {item.tooltip}
                          </Balloon.Tooltip>
                        ) : (
                          trigger
                        );
                      })}
                    </div>
                  );
                })}
              </div>
            </Section>
          )}

          {this.state.billingVisible && (
            <BillingHander
              visi={this.state.billingVisible}
              status={enterprisePackage.status}
              biObj={enterprisePackage}
              isClose={() => this.setState({ billingVisible: false })}
              billingOpenHander={this.props.getOrgplan}
            />
          )}
        </Content>
      </>
    );
  }
}
